﻿using System;
using System.Linq;
using System.Web.Security;

using Telerik.Sitefinity.Security;
using Telerik.Sitefinity.Security.Model;
using Telerik.Sitefinity.Modules.UserProfiles;

namespace Migration.Classes
{
	public static class MigrationUsers
	{
		private static UserManager m_UserManager;
		private static RoleManager m_RoleManager;
		private static UserProfileManager m_UserProfileManager;
		private static Guid m_DefaultOwner;

		static MigrationUsers()
		{
			m_UserManager = UserManager.GetManager(MigrationSettings.UsersProvider);
			m_RoleManager = RoleManager.GetManager(MigrationSettings.RolesProvider);
			m_UserProfileManager = UserProfileManager.GetManager();
			m_DefaultOwner = Guid.Empty;
		}

		private static void CheckManagers()
		{
			if (m_UserManager.Provider == null || MigrationSettings.ApplicationRestarted)
			{
				m_UserManager = UserManager.GetManager(MigrationSettings.UsersProvider);
			}

			if (m_RoleManager.Provider == null || MigrationSettings.ApplicationRestarted)
			{
				m_RoleManager = RoleManager.GetManager(MigrationSettings.RolesProvider);
			}

			if (m_UserProfileManager.Provider == null || MigrationSettings.ApplicationRestarted)
			{
				m_UserProfileManager = UserProfileManager.GetManager();
			}
		}

		public static Guid DefaultOwner
		{
			get
			{
				/*
				// Get the first backend user
				if (m_DefaultOwner == Guid.Empty)
				{
					var allUsers = m_UserManager.GetUsers();
					foreach (var user in allUsers)
					{
						if (m_RoleManager.IsUserInRole(user.Id, SecurityManager.AdminRoleName) ||
							m_RoleManager.IsUserInRole(user.Id, SecurityManager.BackendUsersRoleName))
						{
							m_DefaultOwner = user.Id;
							break;
						}
					}

					if (m_DefaultOwner == Guid.Empty)
					{
						m_DefaultOwner = m_UserManager.GetUsers().FirstOrDefault().Id;
					}
				}
				*/

				if (m_DefaultOwner == Guid.Empty)
				{
					CheckManagers();
					m_DefaultOwner = m_UserManager.GetUsers().FirstOrDefault().Id;
				}

				return m_DefaultOwner;
			}
		}

		public static void ImportUser(Telerik.Sitefinity.Services.Migration.MigrationUser userContent)
		{
			CheckManagers();

			string username = userContent.Username;

			// Check if the user already exists
			var checkUser = m_UserManager.GetUser(username);
			if (checkUser != null)
			{
				MigrationLogger.AppendLogMessage(String.Format("Skipping \"<b>{0}</b>\", already exists.", username));
				return;
			}

			string password = userContent.Password;
			if (String.IsNullOrEmpty(password)) password = "password";
			MembershipCreateStatus status;

			// Create the user
			var newUser = m_UserManager.CreateUser(
				username,
				password,
				userContent.Email,
				userContent.PasswordQuestion == null ? String.Empty : userContent.PasswordQuestion,
				"Answer",
				userContent.IsApproved,
				new Guid(userContent.ProviderUserKey),
				out status);

			if (newUser == null)
			{
				switch (status)
				{
					case MembershipCreateStatus.DuplicateEmail:
						MigrationLogger.AppendLogMessage(String.Format("Could not create user \"<b>{0}</b>\", duplicate email {1}.", username, (userContent.Email == null ? "<i>null</i>" : userContent.Email)));
						return;
					case MembershipCreateStatus.DuplicateUserName:
						MigrationLogger.AppendLogMessage(String.Format("Could not create user \"<b>{0}</b>\", duplicate username {0}.", username));
						return;
					case MembershipCreateStatus.InvalidEmail:
						MigrationLogger.AppendLogMessage(String.Format("Could not create user \"<b>{0}</b>\", invalid email {1}.", username, (userContent.Email == null ? "<i>null</i>" : userContent.Email)));
						return;
					case MembershipCreateStatus.InvalidUserName:
						MigrationLogger.AppendLogMessage(String.Format("Could not create user \"<b>{0}</b>\", invalid username {0}.", username));
						return;
					case MembershipCreateStatus.InvalidProviderUserKey:
						MigrationLogger.AppendLogMessage(String.Format("Could not create user \"<b>{0}</b>\", invalid provider user key {1}.", userContent.ProviderUserKey));
						return;
					default:
						MigrationLogger.AppendLogMessage(String.Format("Could not create user \"<b>{0}</b>\", error code {1}.", username, status));
						return;
				}
			}

			newUser.Comment = userContent.Comment == null ? String.Empty : userContent.Comment;
			newUser.LastActivityDate = userContent.LastActivityDate;
			newUser.LastLoginDate = userContent.LastLoginDate;

			m_UserManager.SaveChanges();

			// Create the basic user profile for the user
			var newUserProfile = (SitefinityProfile)m_UserProfileManager.CreateProfile(newUser, typeof(SitefinityProfile).FullName);
			//newUserProfile.FirstName = ;
			m_UserProfileManager.RecompileItemUrls<SitefinityProfile>(newUserProfile);

			foreach (var roleName in userContent.Roles)
			{
				var role = m_RoleManager.GetRoles().Where(r => r.Name == roleName).SingleOrDefault();
				if (role != null)
				{
					m_RoleManager.AddUserToRole(newUser, role);
				}
			}

			m_RoleManager.SaveChanges();

			MigrationLogger.AppendLogMessage(String.Format("Imported user \"<b>{0}</b>\" with password \"<b>{1}</b>\" and password answer \"<b>Answer</b>\".", username, password));
		}

		public static Guid GetUserByUsername(string username)
		{
			CheckManagers();

			var checkUser = m_UserManager.GetUser(username);
			if (checkUser != null)
				return checkUser.Id;
			else
				return DefaultOwner;
		}
	}
}
